package com.promise.jokerdream.work.penguin

import com.promise.jokerdream.database.entity.EscortGameConfigEntity
import com.promise.jokerdream.config.game.EscortStrategy
import com.promise.jokerdream.repository.foldWithApiException
import com.promise.jokerdream.manager.ExecutionHistoryManager
import com.promise.jokerdream.repository.GameApi
import com.promise.jokerdream.response.pc.QueryEscortChooseResponse
import com.promise.jokerdream.utils.AppContext
import com.promise.jokerdream.work.BaseWork
import com.promise.jokerdream.work.WorkResult

// 押镖选择状态
private enum class EscortSelectionState {
    INITIAL,           // 初始状态
    CHOOSE_ESCORT,     // 选择押镖
    REFRESH_ESCORT,    // 刷新押镖
    START_ESCORT,      // 开始押镖
    CHOOSE_BOSS_LADY,  // 选择老板娘
    COMPLETED,         // 完成
    FAILED            // 失败
}

// 押镖工作
class PenguinEscortWork(
    private val config: EscortGameConfigEntity,
    uin: String
): BaseWork(uin) {
    
    override val name: String
        get() = "押镖"
    
    private val gameApi = GameApi.getInstance()
    private val historyManager by lazy { ExecutionHistoryManager.getInstance(AppContext.get()) }
    
    override suspend fun executeWork(): WorkResult {
        return try {
            // 1. 先通过op=15查询当前押镖状态
            val statusResult = gameApi.queryEscortStatus()
            statusResult.foldWithApiException(
                onSuccess = { statusResponse ->
                    // 如果可领奖则通过op=16领奖
                    if (statusResponse.toAccount == 2) { // 2为护送完成，可领奖
                        val claimResult = gameApi.claimEscortReward()
                        claimResult.foldWithApiException(
                            onSuccess = { claimResponse ->
                                historyManager.addHistory(name, claimResponse.getDescription())
                            },
                            onFailure = { code, msg ->
                                historyManager.addHistory(name, msg, code)
                            }
                        )
                    }

                    return@foldWithApiException
                },
                onFailure = { code, msg ->
                    historyManager.addHistory(name, msg, code)
                }
            )
            
            // 2. 通过op=0查询首页数据
            val homeResult = gameApi.queryEscortHome()
            return homeResult.foldWithApiException(
                onSuccess = { homeResponse ->
                    // conveyCount=0且escortState=0才可以押送
                    if (homeResponse.conveyCount == 0 && homeResponse.escortState == 0) {
                        handleEscortSelection()
                    } else {
                        WorkResult.Success
                    }
                },
                onFailure = { code, msg ->
                    historyManager.addHistory(name, msg, code)
                    WorkResult.Failure(Exception(msg), msg)
                }
            )
        } catch (e: Exception) {
            historyManager.addHistory(name, e.message)
            WorkResult.Failure(e, e.message)
        }
    }
    
    /**
     * 处理押镖选择流程 - 使用状态机
     */
    private suspend fun handleEscortSelection(): WorkResult {
        // 如果只选中老板娘，直接选择老板娘执行
        val selectedNpcIdsList = config.getSelectedNpcIdsList()
        if (selectedNpcIdsList.size == 1 && selectedNpcIdsList.contains(3)) {
            return chooseBossLadyAndStart()
        }
        
        var currentState = EscortSelectionState.INITIAL

        while (currentState != EscortSelectionState.COMPLETED && currentState != EscortSelectionState.FAILED) {
            currentState = when (currentState) {
                EscortSelectionState.INITIAL -> {
                    EscortSelectionState.CHOOSE_ESCORT
                }
                
                EscortSelectionState.CHOOSE_ESCORT -> {
                    val result = gameApi.chooseEscort()
                    result.foldWithApiException(
                        onSuccess = { response ->
                            if (selectedNpcIdsList.contains(response.npcId)) {
                                EscortSelectionState.START_ESCORT
                            } else if (response.reselectTimes > 0) {
                                EscortSelectionState.REFRESH_ESCORT
                            } else {
                                // 没有免费刷新次数，根据配置决定
                                val strategy = try { EscortStrategy.valueOf(config.strategy) } catch (e: Exception) { EscortStrategy.DIRECT_START }
                                if (strategy == EscortStrategy.DIRECT_START) {
                                    EscortSelectionState.START_ESCORT
                                } else {
                                    EscortSelectionState.CHOOSE_BOSS_LADY
                                }
                            }
                        },
                        onFailure = { code, msg ->
                            historyManager.addHistory(name, msg, code)
                            EscortSelectionState.FAILED
                        }
                    )
                }
                
                EscortSelectionState.REFRESH_ESCORT -> {
                    val result = gameApi.refreshEscort()
                    result.foldWithApiException(
                        onSuccess = { response ->
                            if (selectedNpcIdsList.contains(response.npcId)) {
                                EscortSelectionState.START_ESCORT
                            } else if (response.reselectTimes > 0) {
                                // 刷新后仍不匹配，但还有免费刷新次数，继续刷新
                                EscortSelectionState.REFRESH_ESCORT
                            } else {
                                // 刷新后仍不匹配且没有免费刷新次数，根据配置决定
                                val strategy = try { EscortStrategy.valueOf(config.strategy) } catch (e: Exception) { EscortStrategy.DIRECT_START }
                                if (strategy == EscortStrategy.DIRECT_START) {
                                    EscortSelectionState.START_ESCORT
                                } else {
                                    EscortSelectionState.CHOOSE_BOSS_LADY
                                }
                            }
                        },
                        onFailure = { code, msg ->
                            historyManager.addHistory(name, msg, code)
                            EscortSelectionState.FAILED
                        }
                    )
                }
                
                EscortSelectionState.START_ESCORT -> {
                    val result = startEscort()
                    if (result is WorkResult.Success) {
                        EscortSelectionState.COMPLETED
                    } else {
                        EscortSelectionState.FAILED
                    }
                }
                
                EscortSelectionState.CHOOSE_BOSS_LADY -> {
                    val result = chooseBossLadyAndStart()
                    if (result is WorkResult.Success) {
                        EscortSelectionState.COMPLETED
                    } else {
                        EscortSelectionState.FAILED
                    }
                }

                EscortSelectionState.COMPLETED -> EscortSelectionState.COMPLETED
                EscortSelectionState.FAILED -> EscortSelectionState.FAILED
            }
        }
        
        return if (currentState == EscortSelectionState.COMPLETED) {
            WorkResult.Success
        } else {
            WorkResult.Failure(Exception("押镖选择失败"), "押镖选择失败")
        }
    }
    
    /**
     * 开始押镖
     */
    private suspend fun startEscort(): WorkResult {
        val startResult = gameApi.startEscort()
        return startResult.foldWithApiException(
            onSuccess = { startResponse ->
                historyManager.addHistory(name, startResponse.getDescription())
                WorkResult.Success
            },
            onFailure = { code, msg ->
                historyManager.addHistory(name, msg, code)
                WorkResult.Failure(Exception(msg), msg)
            }
        )
    }
    
    /**
     * 选择老板娘后开始押镖
     */
    private suspend fun chooseBossLadyAndStart(): WorkResult {
        val chooseBossResult = gameApi.chooseBossLady()
        return chooseBossResult.foldWithApiException(
            onSuccess = { chooseBossResponse ->
                // 选择老板娘后开始押镖
                startEscort()
            },
            onFailure = { code, msg ->
                historyManager.addHistory(name, msg, code)
                WorkResult.Failure(Exception(msg), msg)
            }
        )
    }
}